import 'package:shared_preferences/shared_preferences.dart';
import 'dart:io';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'exam_service.dart';
import 'student_service.dart';

class DeviceConfigService {
  static const String _isDedicatedDeviceKey = 'is_dedicated_device';
  static const String _dedicatedDevicePathKey = 'dedicated_device_path';
  static const String _defaultDedicatedPath = '/data/userdata/com.westone.examapp';
  
  // 获取是否为专用设备
  static Future<bool> isDedicatedDevice() async {
    final prefs = await SharedPreferences.getInstance();
    return prefs.getBool(_isDedicatedDeviceKey) ?? false;
  }
  
  // 设置是否为专用设备
  static Future<void> setDedicatedDevice(bool isDedicated) async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setBool(_isDedicatedDeviceKey, isDedicated);
  }
  
  // 获取专用设备路径
  static Future<String> getDedicatedDevicePath() async {
    final prefs = await SharedPreferences.getInstance();
    return prefs.getString(_dedicatedDevicePathKey) ?? _defaultDedicatedPath;
  }
  
  // 设置专用设备路径
  static Future<void> setDedicatedDevicePath(String path) async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString(_dedicatedDevicePathKey, path);
  }
  
    // 从专用设备路径自动加载Excel文件
  static Future<Map<String, dynamic>> loadFromDedicatedPath() async {
    final isDedicated = await isDedicatedDevice();
    if (!isDedicated) {
      return {
        'success': false,
        'message': '当前不是专用设备模式',
        'details': []
      };
    }

    final dedicatedPath = await getDedicatedDevicePath();
    final dir = Directory(dedicatedPath);
    
    // 检查目录权限和存在性
    bool dirExists = false;
    try {
      dirExists = await dir.exists();
    } catch (e) {
      return {
        'success': false,
        'message': '无法访问专用设备路径 $dedicatedPath\n权限错误: $e',
        'details': ['请检查应用是否有访问该路径的权限', '可尝试重启应用或更改路径']
      };
    }
    
    // 如果目录不存在，自动创建
    if (!dirExists) {
      try {
        await dir.create(recursive: true);
        debugPrint('自动创建专用设备目录: $dedicatedPath');
        
        // 同时创建其他必要的子目录
        await _createDedicatedDeviceSubDirectories(dedicatedPath);
        
        return {
          'success': false,
          'message': '专用设备路径不存在，已自动创建: $dedicatedPath\n请将Excel文件放入该目录后重新加载',
          'details': ['已创建目录: $dedicatedPath', '已创建子目录: result, answer_images']
        };
      } catch (e) {
        return {
          'success': false,
          'message': '无法创建专用设备路径: $dedicatedPath\n错误: $e',
          'details': []
        };
      }
    }
    
    List<String> details = [];
    bool hasSuccess = false;
    int studentCount = 0, examCount = 0, noticeCount = 0;
    
    try {
      // 获取目录下所有Excel文件
      List<File> allFiles = [];
      try {
        allFiles = dir
            .listSync()
            .whereType<File>()
            .where((f) {
              final name = f.path.toLowerCase();
              return name.endsWith('.xlsx') || name.endsWith('.xls');
            })
            .toList();
      } catch (e) {
        return {
          'success': false,
          'message': '无法列出专用设备路径下的文件\n权限错误: $e',
          'details': ['请检查应用是否有访问该路径的权限', '可尝试重启应用或更改路径']
        };
      }
      
      if (allFiles.isEmpty) {
        return {
          'success': false,
          'message': '在专用设备路径 $dedicatedPath 下未找到Excel文件',
          'details': ['请确保目录下有学生信息.xlsx和试卷_xxx.xlsx文件']
        };
      }
      
      // 检查是否需要重新加载数据
      final shouldReload = await shouldReloadExamData(allFiles);
      if (shouldReload) {
        debugPrint('检测到Excel文件变化，重新加载考试数据');
        await ExamService.clearAllExams();
      } else {
        debugPrint('Excel文件未变化，使用缓存的考试数据');
        // 如果文件未变化且已有考试数据，直接返回成功
        final existingExams = ExamService.getAllExams();
        if (existingExams.isNotEmpty) {
          return {
            'success': true,
            'message': '使用缓存数据，共有 ${existingExams.length} 套试题',
            'details': existingExams.map((e) => '试题: ${e.title}').toList(),
            'counts': {
              'students': StudentService.getStudents().length,
              'exams': existingExams.length,
              'notices': 0,
            }
          };
        }
      }
      
      // 处理每个文件
      for (final file in allFiles) {
        final filename = file.path.split('/').last;
        
        try {
          if (filename == '学生信息.xlsx' || filename == '学生信息.xls') {
            final result = await StudentService.importFromExcel(file);
            details.add('学生信息: $filename => ${result.message}');
            if (result.success) {
              studentCount++;
              hasSuccess = true;
            }
          } else if (filename == '考试须知.xlsx' || filename == '考试须知.xls') {
            details.add('须知: $filename => 发现文件但暂不支持自动导入');
            noticeCount++;
            // 如果将来支持须知导入，可以在这里添加
          } else {
            // 检查是否是试卷文件（试卷ID_试卷名称_试卷序号_考试时间.xlsx或.xls格式）
            print('filename: $filename  ----------------------------');
            final matchXlsx = RegExp(r'^(.+)_(.+)_(\d+)_(\d+)\.xlsx$').firstMatch(filename);
            final matchXls = RegExp(r'^(.+)_(.+)_(\d+)_(\d+)\.xls$').firstMatch(filename);
            final match = matchXlsx ?? matchXls;
            print('match: $match  ----------------------------');
            if (match != null) {
              final examId = match.group(1)!;  // 试卷ID
              final examTitle = match.group(2)!;  // 试卷名称
              final examSequence = match.group(3)!;  // 试卷序号
              final durationStr = match.group(4)!;  // 考试时间
              final sequence = int.tryParse(examSequence) ?? 1;  // 默认序号1
              final duration = int.tryParse(durationStr) ?? 60;  // 默认60分钟
              
              final exam = await ExamService.createExamFromExcelFile(
                file,
                title: examTitle,
                description: examTitle,
                duration: duration,
                originalId: examId,
              );
              details.add('试题: $filename => ${exam != null ? '导入成功，共${exam.questions.length}道题，时长$duration分钟' : '导入失败'}');
              if (exam != null) {
                examCount++;
                hasSuccess = true;
              }
            } else {
              details.add('跳过: $filename => 文件名格式不符合要求（应为：id_试卷名称_考试时长.xlsx）');
            }
          }
        } catch (e) {
          details.add('$filename => 导入失败: $e');
        }
      }
      
      final message = '专用设备自动加载完成:\n'
          '学生信息: $studentCount 个文件导入成功\n'
          '试题信息: $examCount 个文件导入成功\n'
          '考试须知: $noticeCount 个文件导入成功';
      
      return {
        'success': hasSuccess,
        'message': message,
        'details': details,
        'counts': {
          'students': studentCount,
          'exams': examCount,
          'notices': noticeCount,
        }
      };
      
    } catch (e) {
      return {
        'success': false,
        'message': '专用设备路径加载失败: $e',
        'details': details
      };
    }
  }
  
  // 检查专用设备路径是否有效
  static Future<bool> isValidDedicatedPath(String path) async {
    try {
      final dir = Directory(path);
      return await dir.exists();
    } catch (e) {
      debugPrint('检查专用设备路径失败: $e');
      return false;
    }
  }

  // 测试专用设备路径的读写权限
  static Future<Map<String, dynamic>> testDedicatedPathPermissions() async {
    final dedicatedPath = await getDedicatedDevicePath();
    final dir = Directory(dedicatedPath);
    
    Map<String, bool> testResults = {
      'pathExists': false,
      'canRead': false,
      'canWrite': false,
      'canList': false,
    };
    
    List<String> details = [];
    
    try {
      // 1. 测试路径是否存在
      testResults['pathExists'] = await dir.exists();
      if (testResults['pathExists']!) {
        details.add('✓ 路径存在: $dedicatedPath');
      } else {
        details.add('✗ 路径不存在: $dedicatedPath');
        return {
          'success': false,
          'message': '专用设备路径测试失败',
          'details': details,
          'results': testResults,
        };
      }
      
      // 2. 测试目录列表权限
      try {
        final files = dir.listSync();
        testResults['canList'] = true;
        details.add('✓ 可以列出目录内容，发现 ${files.length} 个文件/文件夹');
      } catch (e) {
        testResults['canList'] = false;
        details.add('✗ 无法列出目录内容: $e');
      }
      
      // 3. 测试读取权限
      try {
        final testFile = File('$dedicatedPath/test_read.txt');
        if (await testFile.exists()) {
          await testFile.readAsString();
          testResults['canRead'] = true;
          details.add('✓ 可以读取文件');
        } else {
          testResults['canRead'] = true; // 目录可访问即可读
          details.add('✓ 具有读取权限');
        }
      } catch (e) {
        testResults['canRead'] = false;
        details.add('✗ 读取权限测试失败: $e');
      }
      
      // 4. 测试写入权限
      try {
        final testFile = File('$dedicatedPath/test_write_permission.txt');
        await testFile.writeAsString('权限测试 ${DateTime.now()}');
        testResults['canWrite'] = true;
        details.add('✓ 可以写入文件');
        
        // 清理测试文件
        if (await testFile.exists()) {
          await testFile.delete();
          details.add('✓ 已清理测试文件');
        }
      } catch (e) {
        testResults['canWrite'] = false;
        details.add('✗ 写入权限测试失败: $e');
      }
      
      final allTestsPassed = testResults.values.every((test) => test);
      
      return {
        'success': allTestsPassed,
        'message': allTestsPassed ? '所有权限测试通过' : '部分权限测试失败',
        'details': details,
        'results': testResults,
      };
      
    } catch (e) {
      details.add('✗ 权限测试过程出错: $e');
      return {
        'success': false,
        'message': '权限测试失败',
        'details': details,
        'results': testResults,
      };
    }
  }
  
  // 获取专用设备路径下的Excel文件列表
  static Future<List<String>> getExcelFilesInDedicatedPath() async {
    final dedicatedPath = await getDedicatedDevicePath();
    final dir = Directory(dedicatedPath);
    
    if (!await dir.exists()) {
      return [];
    }
    
    try {
      final files = dir
          .listSync()
          .whereType<File>()
          .where((f) => f.path.toLowerCase().endsWith('.xlsx') || f.path.toLowerCase().endsWith('.xls'))
          .map((f) => f.path.split('/').last)
          .toList();
      
      return files;
    } catch (e) {
      debugPrint('获取Excel文件列表失败: $e');
      return [];
    }
  }
  
  // 创建专用设备必要的子目录
  static Future<void> _createDedicatedDeviceSubDirectories(String basePath) async {
    try {
      // 创建result目录
      final resultDir = Directory('$basePath/result');
      if (!await resultDir.exists()) {
        await resultDir.create(recursive: true);
        debugPrint('已创建result目录: ${resultDir.path}');
      }
      
      // 创建answer_images目录
      final imagesDir = Directory('$basePath/answer_images');
      if (!await imagesDir.exists()) {
        await imagesDir.create(recursive: true);
        debugPrint('已创建answer_images目录: ${imagesDir.path}');
      }
    } catch (e) {
      debugPrint('创建专用设备子目录失败: $e');
    }
  }
  
  // 确保专用设备相关目录存在
  static Future<void> ensureDedicatedDeviceDirectories() async {
    final isDedicated = await isDedicatedDevice();
    if (!isDedicated) return;
    
    final dedicatedPath = await getDedicatedDevicePath();
    
    try {
      // 确保主目录存在
      final mainDir = Directory(dedicatedPath);
      if (!await mainDir.exists()) {
        await mainDir.create(recursive: true);
        debugPrint('已创建专用设备主目录: $dedicatedPath');
      }
      
      // 确保子目录存在
      await _createDedicatedDeviceSubDirectories(dedicatedPath);
    } catch (e) {
      debugPrint('确保专用设备目录失败: $e');
    }
  }
  
  // 检查是否需要重新加载考试数据
  static Future<bool> shouldReloadExamData(List<File> currentFiles) async {
    try {
      final prefs = await SharedPreferences.getInstance();
      
      // 获取当前文件的信息（文件名和修改时间）
      final Map<String, int> currentFileInfo = {};
      for (final file in currentFiles) {
        final filename = file.path.split('/').last;
        final stat = await file.stat();
        currentFileInfo[filename] = stat.modified.millisecondsSinceEpoch;
      }
      
      // 获取上次保存的文件信息
      final savedFileInfoJson = prefs.getString('dedicated_device_file_info');
      if (savedFileInfoJson == null) {
        // 第一次加载，需要重新加载
        await saveFileInfo(currentFileInfo);
        return true;
      }
      
      final Map<String, dynamic> savedFileInfo = jsonDecode(savedFileInfoJson);
      
      // 比较文件数量
      if (currentFileInfo.length != savedFileInfo.length) {
        await saveFileInfo(currentFileInfo);
        return true;
      }
      
      // 比较每个文件的修改时间
      for (final entry in currentFileInfo.entries) {
        final filename = entry.key;
        final modifiedTime = entry.value;
        
        if (!savedFileInfo.containsKey(filename) || 
            savedFileInfo[filename] != modifiedTime) {
          await saveFileInfo(currentFileInfo);
          return true;
        }
      }
      
      // 文件没有变化
      return false;
      
    } catch (e) {
      debugPrint('检查文件变化失败: $e');
      // 出错时重新加载
      return true;
    }
  }
  
  // 保存文件信息
  static Future<void> saveFileInfo(Map<String, int> fileInfo) async {
    try {
      final prefs = await SharedPreferences.getInstance();
      await prefs.setString('dedicated_device_file_info', jsonEncode(fileInfo));
    } catch (e) {
      debugPrint('保存文件信息失败: $e');
    }
  }
} 